package be.phl.android.project;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import persist.Activiteit;
import persist.Dagmenu;

import android.content.Context;
import android.text.format.Time;
import android.util.Log;

/**
 * @author Sey Vaneerdewegh
 * 
 */
public class JsonHandler {
	private static final JsonHandler instance = new JsonHandler();
	private static String filename = "data.json";
	private static String url = "http://10.0.2.2/data_json.txt";
	private Context ctx;

	private JsonHandler() {
	}

	public static JsonHandler getInstance() {
		return instance;
	}

	public void setContext(Context c) {
		ctx = c;
	}

	private String readLocal() {
		try {
			String filepath = ctx.getFilesDir().getAbsolutePath();
			File file = new File(filepath, filename);
			byte[] buffer = new byte[(int) file.length()];
			String content = "";

			FileInputStream fis = new FileInputStream(file);
			fis.read(buffer);
			fis.close();

			content = new String(buffer);
			return content;

		} catch (FileNotFoundException e) {
			Log.e("JSONHandler read error", "Can't open file: " + e.toString());
			return null;
		} catch (IOException e) {
			Log.e("JSONHandler read error",
					"Error in reading file: " + e.toString());
			return null;
		} catch (Exception e) {
			Log.e("JSONHandler read error", "Something went horribly wrong! "
					+ e.toString());
			return null;
		}

	}

	public void update() {
		InputStream is = null;
		OutputStreamWriter writer = null;
		try {
			if (ctx == null) {
				throw new Exception("Context needs to be set.");
			}

			// Haal de tijd op en deze tijdelijk opslaan in stringformat
			Time now = new Time();
			now.setToNow();
			String last_update = now.toString();

			// een http request doen op de url en deze opslaan in de inputstream
			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpGet httpget = new HttpGet(url);
			HttpResponse response = httpclient.execute(httpget);
			is = response.getEntity().getContent();
			// lees de inputstream in een buffer, bouw er een string mee en
			// steek in het JSONObject data
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(is));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
			is.close();
			// checken of het een valid json-string is. Bij foutieve string
			// wordt er hier een exception gegooid.
			String result = sb.toString();
			JSONObject checkJSON = new JSONObject(result);

			// zet de opgevraagde tijd in data. In het 2de trimester wordt dit
			// op serverside gedaan.
			checkJSON.put("last_update", last_update);

			// schrijf de nieuwe data naar de datafile
			FileOutputStream fOut = ctx.openFileOutput(filename,
					ctx.MODE_PRIVATE);
			writer = new OutputStreamWriter(fOut);
			writer.write(checkJSON.toString());
			writer.flush();
			writer.close();
		} catch (ClientProtocolException e) {
			Log.e("JSONHandler update error",
					"Error with http: " + e.toString());
		} catch (IllegalArgumentException e) {
			Log.e("JSONHandler update error",
					"Error with arguments: " + e.toString());
		} catch (JSONException e) {
			Log.e("JSONHandler update error",
					"Error with JSON: " + e.toString());
		} catch (IOException e) {
			Log.e("JSONHandler update error", "Error with IO: " + e.toString());
		} catch (Exception e) {
			Log.e("JSONHandler update error", "Something went horribly wrong! "
					+ e.toString());
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	public String getLastUpdate() {
		try {
			JSONObject data = new JSONObject(readLocal());
			return data.getString("last_update");
		} catch (JSONException e) {
			Log.e("JSONHandler getLastUpdate error",
					"Error with JSON: " + e.toString());
			return null;
		} catch (Exception e) {
			Log.e("JSONHandler getLastUpdate error",
					"Something went horribly wrong!" + e.toString());
			return null;
		}

	}

	public Activiteit[][] getLessenrooster() {
		Activiteit[][] output = new Activiteit[6][];
		try {
			JSONObject data = new JSONObject(readLocal());
			JSONObject lessenrooster = data.getJSONObject("lessenrooster");
			JSONArray[] week = new JSONArray[6];
			week[0] = lessenrooster.getJSONArray("maandag");
			week[1] = lessenrooster.getJSONArray("dinsdag");
			week[2] = lessenrooster.getJSONArray("woensdag");
			week[3] = lessenrooster.getJSONArray("donderdag");
			week[4] = lessenrooster.getJSONArray("vrijdag");
			week[5] = lessenrooster.getJSONArray("zaterdag");
			for (int weekdag = 0; weekdag < week.length; weekdag++) {
				int aantalLessen = week[weekdag].length();
				output[weekdag] = new Activiteit[aantalLessen];
				for (int lesIndex = 0; lesIndex < week[weekdag].length(); lesIndex++) {
					JSONObject les = week[weekdag].getJSONObject(lesIndex);
					JSONArray leerkrachten = les.getJSONArray("leerkracht");
					String l = "";
					for (int i = 0; i < leerkrachten.length(); i++) {
						l += leerkrachten.getString(i);
						if (i < leerkrachten.length() - 1)
							l += ", ";
					}

					output[weekdag][lesIndex] = new Activiteit(
							les.getString("begin"), les.getString("naam"),
							les.getString("lokaal"), l, les.getString("einde"));
				}
			}
			return output;
		} catch (JSONException e) {
			Log.e("JSONHandler getLessenrooster error",
					"Error with JSON: " + e.toString());
			return null;
		}

	}

	public Dagmenu getDagmenu() {
		Dagmenu output = null;

		try {
			JSONObject data = new JSONObject(readLocal());
			JSONObject dagmenu = data.getJSONObject("dagmenu");
			JSONArray soepArray = dagmenu.getJSONArray("soep");
			JSONArray hoofdgerechtArray = dagmenu.getJSONArray("hoofdgerecht");
			String soep = "";
			String hoofdgerecht = "";

			for (int i = 0; i < soepArray.length(); i++) {
				soep += soepArray.getString(i);
				if (i < soepArray.length() - 1)
					soep += ", ";
			}
			for (int i = 0; i < hoofdgerechtArray.length(); i++) {
				hoofdgerecht += hoofdgerechtArray.getString(i);
				if (i < hoofdgerechtArray.length() - 1)
					hoofdgerecht += ", ";
			}
			output = new Dagmenu(soep, hoofdgerecht,
					dagmenu.getString("opmerking"),
					dagmenu.getString("weeksoep"), dagmenu.getString("veggie"),
					dagmenu.getString("met_smaak"),
					dagmenu.getString("aanrader"));
			return output;
		} catch (JSONException e) {
			Log.e("JSONHandler getDagmenu error",
					"Error with JSON: " + e.toString());
			return null;
		}

	}

}
